﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using ZFY.Core;
using ZFY.UnitOfWork.Interface;

namespace ZFY.UnitOfWork
{
    public class ChildUnitOfWork : IZFYUnitOfWork,IScopeDependency
    {
        public Guid Id => _parent.Id;

        public UnitOfWorkOption Options => _parent.Options;

        public IZFYUnitOfWork Outer => _parent.Outer;


        public bool IsDisposed => _parent.IsDisposed;

        public bool IsCompleted => _parent.IsCompleted;


        public IServiceProvider ServiceProvider => _parent.ServiceProvider;

        private readonly IZFYUnitOfWork _parent;

        public event EventHandler<UnitOfWorkFailedEventArgs> Failed;
        public event EventHandler<UnitOfWorkEventArgs> Disposed;

        public ChildUnitOfWork([NotNull] IZFYUnitOfWork parent)
        {

            _parent = parent;

            _parent.Failed += (sender, args) => { Failed.InvokeSafely(sender, args); };
            _parent.Disposed += (sender, args) => { Disposed.InvokeSafely(sender, args); };
        }

        public void SetOuter(IZFYUnitOfWork outer)
        {
            _parent.SetOuter(outer);
        }

        public void Initialize(UnitOfWorkOption options)
        {
            _parent.Initialize(options);
        }


        public Task SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            return _parent.SaveChangesAsync(cancellationToken);
        }

        public Task CompleteAsync(CancellationToken cancellationToken = default)
        {
            return Task.CompletedTask;
        }

        public Task RollbackAsync(CancellationToken cancellationToken = default)
        {
            return _parent.RollbackAsync(cancellationToken);
        }

        public void OnCompleted(Func<Task> handler)
        {
            _parent.OnCompleted(handler);
        }

        public IDbContextApi FindDbContext(string key)
        {
            return _parent.FindDbContext(key);
        }

        public void AddDbContext(string key, IDbContextApi api)
        {
            _parent.AddDbContext(key, api);
        }


        public ITransactionApi FindDbTransaction(string key)
        {
            return _parent.FindDbTransaction(key);
        }

        public void AddDbTransaction(string key, ITransactionApi api)
        {
            _parent.AddDbTransaction(key, api);
        }


        public void Dispose()
        {

        }

        public override string ToString()
        {
            return $"[UnitOfWork {Id}]";
        }
    }
}
